// MainDlg.h : interface of the CMainDlg class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

#include "everything_ipc.h"
#include <string>
using namespace std;

#include "WorkerPool.h"

#define COPYDATA_IPCTEST_QUERYCOMPLETEW	0
#define COPYDATA_IPCTEST_QUERYCOMPLETEA	1
#define COPYDATA_MD5_UPDATE	3

DWORD starttime;

class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>,
		public CMessageFilter, public CIdleHandler
{
	CWorkerPool pool;

	CStatic m_md5ctrl;
	CEdit m_ext;
public:
	enum { IDD = IDD_MAINDLG };

	virtual BOOL PreTranslateMessage(MSG* pMsg)
	{
		return CWindow::IsDialogMessage(pMsg);
	}

	virtual BOOL OnIdle()
	{
		return FALSE;
	}

	BEGIN_UPDATE_UI_MAP(CMainDlg)
	END_UPDATE_UI_MAP()

	BEGIN_MSG_MAP(CMainDlg)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_COPYDATA, OnCopyData)

		MESSAGE_HANDLER(WM_UPDATEMD5, OnUpdateMD5)

		

		COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
		COMMAND_ID_HANDLER(IDOK, OnOK)
		COMMAND_ID_HANDLER(IDCANCEL, OnCancel)

		COMMAND_ID_HANDLER(ID_APP_PROCESS, OnAppProcess)

		
	END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// center the dialog on the screen
		CenterWindow();

		// set icons
		HICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
		SetIcon(hIcon, TRUE);
		HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
		SetIcon(hIconSmall, FALSE);

		// register object for message filtering and idle updates
		CMessageLoop* pLoop = _Module.GetMessageLoop();
		ATLASSERT(pLoop != NULL);
		pLoop->AddMessageFilter(this);
		pLoop->AddIdleHandler(this);

		UIAddChildWindowContainer(m_hWnd);

		m_md5ctrl = GetDlgItem(IDC_MD5);
		m_ext = GetDlgItem(IDC_EDIT_EXT);
		m_ext.SetWindowText(_T("*.pdf"));

		return TRUE;
	}

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// unregister message filtering and idle updates
		CMessageLoop* pLoop = _Module.GetMessageLoop();
		ATLASSERT(pLoop != NULL);
		pLoop->RemoveMessageFilter(this);
		pLoop->RemoveIdleHandler(this);

		return 0;
	}

	LRESULT OnUpdateMD5(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		m_md5ctrl.SetWindowText(_T(""));
		return 0;
	}

	

	LRESULT OnCopyData(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		COPYDATASTRUCT *cds = (COPYDATASTRUCT *)lParam;
		CWorker* pWorker = NULL;
		EVERYTHING_IPC_LIST *list = NULL;
		vector<TCHAR*>* pFiles = NULL;
		switch(cds->dwData)
		{
			case COPYDATA_IPCTEST_QUERYCOMPLETEA:
				//listresultsA((EVERYTHING_IPC_LIST *)cds->lpData);
				return TRUE;

			case COPYDATA_IPCTEST_QUERYCOMPLETEW:
				//listresultsW((EVERYTHING_IPC_LIST *)cds->lpData);

				pFiles = new vector<TCHAR*>;
				list = (EVERYTHING_IPC_LIST *)cds->lpData;

				for(int i = 0; i < list->numitems; i++)
				{
					if (list->items[i].flags & EVERYTHING_IPC_DRIVE)
					{
						printf("DRIVE %S\n",EVERYTHING_IPC_ITEMFILENAME(list,&list->items[i]));
					}
					else if (list->items[i].flags & EVERYTHING_IPC_FOLDER)
					{
						wchar_t *p;

						p = EVERYTHING_IPC_ITEMFILENAME(list,&list->items[i]);

						while(*p)
						{
							printf("%d (%c)\n",*p,*p);
							p++;
						}

						//			printf("FOLDER %S\\%S\n",EVERYTHING_IPC_ITEMPATH(list,&list->items[i]),EVERYTHING_IPC_ITEMFILENAME(list,&list->items[i]));
						//			printf("FOLDER %S\\%S\n",EVERYTHING_IPC_ITEMPATH(list,&list->items[i]),EVERYTHING_IPC_ITEMFILENAME(list,&list->items[i]));
					}
					else
					{
						TCHAR* s = new TCHAR[MAX_PATH];
						_tcscpy(s, EVERYTHING_IPC_ITEMPATH(list, &list->items[i] ));
						_tcscat(s, _T("\\"));
						_tcscat(s, EVERYTHING_IPC_ITEMFILENAME(list,&list->items[i]));
						pFiles->push_back(s);

						//ATLTRACE( atlTraceUI, 0, _T("%s%s\n"), EVERYTHING_IPC_ITEMPATH(list, &list->items[i] ),EVERYTHING_IPC_ITEMFILENAME(list,&list->items[i]));
					}
				}

				pWorker = pool.getWorker();
				pWorker->hwnd = this->m_hWnd;
				pWorker->assign(pFiles);
				pWorker->start();

				break;

			case COPYDATA_MD5_UPDATE:
				CString strRecievedText = (LPCSTR) (cds->lpData);
				m_md5ctrl.SetWindowText(strRecievedText);
				break;

		}
		return 0;
	}

	

	LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CAboutDlg dlg;
		dlg.DoModal();
		return 0;
	}

	LRESULT OnAppProcess(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		TCHAR sTitle[10];
		m_ext.GetWindowText(sTitle, 10);
		sendqueryW( m_hWnd, sTitle );
		return 0;
	}

	LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		// TODO: Add validation code 
		CloseDialog(wID);
		return 0;
	}

	LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CloseDialog(wID);
		return 0;
	}

	void CloseDialog(int nVal)
	{
		DestroyWindow();
		::PostQuitMessage(nVal);
	}

// query everything with search string
int sendqueryW(HWND hwnd,WCHAR *search_string)
{
	EVERYTHING_IPC_QUERY *query;
	int len;
	int size;
	HWND everything_hwnd;
	COPYDATASTRUCT cds;
	
	starttime = GetTickCount();
	
	everything_hwnd = FindWindow(EVERYTHING_IPC_WNDCLASS,0);
	if (everything_hwnd)
	{
		len = (int)wcslen(search_string);
		
		size = sizeof(EVERYTHING_IPC_QUERY) - sizeof(WCHAR) + len*sizeof(WCHAR) + sizeof(WCHAR);
		
		query = (EVERYTHING_IPC_QUERY *)HeapAlloc(GetProcessHeap(),0,size);
		if (query)
		{
			query->max_results = EVERYTHING_IPC_ALLRESULTS;
			query->offset = 0;
			query->reply_copydata_message = COPYDATA_IPCTEST_QUERYCOMPLETEW;
			query->search_flags = 0;
			query->reply_hwnd = hwnd;
			CopyMemory(query->search_string,search_string,(len+1)*sizeof(WCHAR));
		
			cds.cbData = size;
			cds.dwData = EVERYTHING_IPC_COPYDATAQUERY;
			cds.lpData = query;

			if (SendMessage(everything_hwnd,WM_COPYDATA,(WPARAM)hwnd,(LPARAM)&cds) == TRUE)
			{
				printf("Query sent.\n");
				HeapFree(GetProcessHeap(),0,query);
				
				return 1;
			}
			else
			{
				printf("Everything IPC service not running.\n");
			}

			HeapFree(GetProcessHeap(),0,query);
		}
		else
		{
			printf("failed to allocate %d bytes for IPC query.\n",size);
		}
	}
	else
	{
		// the everything window was not found.
		// we can optionally RegisterWindowMessage("EVERYTHING_IPC_CREATED") and 
		// wait for Everything to post this message to all top level windows when its up and running.
		printf("Everything IPC window not found, IPC unavailable.\n");
	}

	return 0;
}


};
